#include "main.h"

// GPIO1_1
#define Check_gpio_num      "1"

int fd_tx_fifo = 0;
int fd_rx_fifo = 0;
int fd_check = 0;
u_int8_t motor_dir = 0;     //1开
sem_t sem_motor;
sem_t sem_led;


int main(int argc, char *argv[])
{
    int ret;
    int vol;
    u_int8_t rx_data = 0;
    ret = create_fifo();
    printf("11\n");
    if( ret != 0 ){
        printf("create_fifo error!\n");
        exit(-1);
    }
    ret = mysem_init();
    printf("22\n");
    if( ret != 0 ){
        printf("mysem_init error!\n");
        exit(-1);
    }
    ret = pthread_init();
    printf("33\n");
    if( ret != 0 ){
        printf("pthread_init error!\n");
        exit(-1);
    }
    ret = open_check_gpio();
    if( ret != 0 ){
        printf("open_check_gpio error!\n");
        exit(-1);
    }
    /* 等待线程初始化完 */
    printf("to wait led sem!\n");
    sem_wait(&sem_led);
    printf("to wait motor sem!\n");
    sem_wait(&sem_motor);
    printf("ready to while(1)\n");
    usleep(10*1000);


    while (1)
    {
        restart:
        /* code */
        /*检测车辆到达位置*/
        while (1)
        {
            vol = check_gpio_read();
            printf("%d \n",vol);
            if( vol == -1 ){
                printf("check gpio read error!\n");
                exit(-1);
            }
            if( vol == 0 ){
                // printf("%d \n",vol);
                break;
            }
            // else{
                printf("%d \n",vol);
            // }
            usleep(300*1000);
        }
        printf("while 1 out\n");
        /*开启识别灯光 并向qt发送识别请求*/
        sem_post(&sem_led);
        ret = write(fd_tx_fifo, "1", 1);
        if( ret != 1 ){
            if(write(fd_tx_fifo, "1", 1) != 1){
                printf("write to fd_tx_fifo error!\n");
                exit(-1);
            }
        }
        printf("666666\n");
        /*等待识别结果*/
        while (1)
        {
            /* code */
            printf("777777\n");
            /*判断识别结果*/
            ret = read(fd_rx_fifo, &rx_data, 1);
            printf("888888\n");
            if( ret > 0 ){
                printf("rx_data = %c\n",rx_data);
                    /*识别成功*/
                if( rx_data == '1' ){
                    /*使能motor*/
                    sem_post(&sem_motor);
                    break;
                }
                if( rx_data == '0' ){
                    goto restart;
                }
            }
            usleep(300*1000);
        }

        /*识别车辆离开*/
        while (1)
        {
            /* code */
            vol = check_gpio_read();
            printf("%d \n",vol);
            if( vol == -1 ){
                printf("check gpio read2 error!\n");
                exit(-1);
            }
            else if( vol == 1 ){
                // printf("%d \n",vol);
                break;
            }
            usleep(300*1000);
        }
        printf("while 2 out\n");
        sem_post(&sem_led);
        sem_post(&sem_motor);
        // usleep(300*1000);
        sleep(3);
    }
    
    return 0;
}






int create_fifo(void)
{
    int ret;
    if( access("/home/debian/tmp/cfifo", F_OK) != 0 ){
        ret = mkfifo("/home/debian/tmp/cfifo", 0777);
        if( ret != 0 ){
            printf("cfifo create error!\n");
            return -1;
        }
    }
    printf("1\n");
    fd_rx_fifo = open("/home/debian/tmp/cfifo", O_RDWR | O_NONBLOCK);
    if( fd_rx_fifo < 0 ){
        printf("fd_rx_fifo open error!\n");
        return -1;
    }
    printf("2\n");
    if( access("/home/debian/tmp/qfifo", F_OK) != 0 ){
        ret = mkfifo("/home/debian/tmp/qfifo", 0777);
        if( ret != 0 ){
            printf("qfifo create error!\n");
            return -1;
        }
    }
    printf("3\n");
    fd_tx_fifo = open("/home/debian/tmp/qfifo", O_RDWR | O_NONBLOCK);
    if( fd_tx_fifo < 0 ){
        printf("fd_tx_fifo open error!\n");
        return -1;
    }
    return 0;
}

int open_check_gpio(void)
{
        /* 导出io口节点到用户空间*/
    if( access("/sys/class/gpio/gpio"Check_gpio_num, F_OK) != 0 ){
        fd_check = open("/sys/class/gpio/export", O_WRONLY);
        if( fd_check < 0 ){
        printf("Check_gpio_num export open error\n");
        return -1;
        }
        if( write(fd_check, Check_gpio_num, sizeof(Check_gpio_num)) != sizeof(Check_gpio_num) ){
        printf("Check_gpio_num write export error\n");
        return -1;
        }
    }
    /*设置io口为输入模式*/
    fd_check = open("/sys/class/gpio/gpio"Check_gpio_num"/direction", O_WRONLY);
    if( fd_check < 0 ){
        printf("Check_gpio_num direction open error\n");
        return -1;
    }
    if( write(fd_check, "in", 2) != 2 ){
        printf("Check_gpio_num write direction error\n");
        return -1;
    }
    /*设置io口电平*/
    fd_check = open("/sys/class/gpio/gpio" Check_gpio_num "/value", O_RDONLY);
    if( fd_check < 0 ){
        printf("Check_gpio_num value open error\n");
        return -1;
    }
    return 0;
}

int check_gpio_read(void)
{
    u_int8_t vol;
    if( read(fd_check, &vol, 1) > 0 ){
            // printf("%c\n", vol);
            lseek(fd_check, SEEK_SET, 0);
            if( vol == '0' )
                return 0;
            if( vol == '1' )
                return 1;
    }
    else
        return -1;
}


int mysem_init(void)
{
    int ret;
    ret = sem_init(&sem_led, 0, 0);
    if( ret < 0 ){
        printf("sem_led init error!\n");
        return -1;
    }
    ret = sem_init(&sem_motor, 0, 0);
    if( ret < 0 ){
        printf("sem_motor init error!\n");
        return -1;
    }

    return 0;
}

int pthread_init(void)
{
    int ret;
    pthread_t motor_p, idled_p;
    ret = pthread_create(&motor_p, NULL, motor_task, NULL);
    if(ret != 0){
        printf("motor_task creat error!\n");
        return -1;
    }
    ret = pthread_create(&idled_p, NULL, id_led_task, NULL);
    if(ret != 0){
        printf("id_led_task creat error!\n");
        return -1;
    }

    return 0;
}

void *motor_task(void *arg)
{
    motor_init();
}

void *id_led_task(void *arg)
{
    id_led_init();
}
